package com.hongxin.nw.netty.utils;

import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;

/**
 * @remark 字段解析
 * @author: GuoXiaolin
 * @date 2019/6/17 15:10
 * @Version 1.0
 * @Descibe
 */
@Slf4j
public class FieldAnalysis {

    private static int toInt(String s){
        return Integer.parseInt(BinaryTools.converter(s),16);
    }
    /**
     * 七个八位位组二进制时间 CP56 {毫秒，分，时，日，月，年（年—2000）}。
     * 转换为正常时间格式
     */
    public static String hexToTime(String t) {
        String sss = t.substring(0, 4);
        int ms = toInt(sss)%60;
        int second = toInt(sss)/1000;
        int min = toInt(t.substring(4, 6));
        int hours = toInt(t.substring(6, 8));
        int day = toInt(t.substring(8, 10));
        int mouth = toInt(t.substring(10, 12));
        int year = toInt(t.substring(12)) + 2000;

        return year + "-" + mouth + "-" + day + " " + hours + ":" + min + ":" + second + "." + ms;
    }

    /**
     * 说明: bin转正常格式
     * 1:字符串高低位转换
     * 2:高位减零
     * 3:转int
     * @param str 字符串
     * @return 返回
     */
    public static String analysisBin(String str){
        return String.valueOf(Long.parseLong(BinaryTools.reduceZero(BinaryTools.converter(str)), 16));
    }

    /**
     * 说明: BCD转正常格式
     * 1:字符串高低位转换
     * 2:高位减零
     * @param str 字符
     * @return 返回
     */
    public static String analysisBCD(String str){
        return BinaryTools.reduceZero(BinaryTools.converter(str));
    }

    /**
     *
     * 精确到小数后 w 位转16进制,
     * @param num 值
     * @param w 小数点后多少位
     * @return 返回4字节
     */
    public static String hexToDecimal(String num, Integer w) {
        Long ia = Long.valueOf(analysisBin(num));
        if (w==1){
            return OctTodecimal(ia);
        }
        if (w==2){
            return OctTodecimal2(ia);
        }
        if (w==3){
            return OctTodecimal3(ia);
        }
        if (w==5){
            return OctTodecimal5(ia);
        }
        return null;
    }


    /**
     * 设备信息转十进制
     */
    public static String toOct(String str) {
        String s1 = BinaryTools.converter(str);
        String s2 = BinaryTools.reduceZero(s1);
        if (s2 == null){
            return "0";
        }
        return String.valueOf(Integer.parseInt(s2,16));
    }

    /**
     * 16进制转小数精确到后1位
     */
    private static String OctTodecimal(Long num) {
        BigDecimal temp = BigDecimal.valueOf(num);
        // 将temp除以10
        temp = temp.divide(BigDecimal.valueOf(10), 1, BigDecimal.ROUND_HALF_UP);
        return String.valueOf(temp);
    }

    /**
     * 16进制转小数精确到后2位
     */
    private static String OctTodecimal2(Long num) {
        BigDecimal temp = BigDecimal.valueOf(num);
        // 将temp除以100
        temp = temp.divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
        return String.valueOf(temp);
    }

    /**
     * 16进制转小数精确到后3位
     */
    private static String OctTodecimal3(Long num) {
        BigDecimal temp = BigDecimal.valueOf(num);
        // 将temp除以1000
        temp = temp.divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_HALF_UP);
        return String.valueOf(temp);
    }
    /**
     * 16进制转小数精确到后5位
     */
    private static String OctTodecimal5(Long num) {

        BigDecimal temp = BigDecimal.valueOf(num);
        // 将temp除以100000
        temp = temp.divide(BigDecimal.valueOf(100000), 5, BigDecimal.ROUND_HALF_UP);
        return String.valueOf(temp);
    }

    /**
     * 设备编码
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subCo(int byteLength, int idx, ByteBuf byteBuf){
        String co;
        co = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        co = FieldAnalysis.analysisBCD(co);
        return co;
    }

    /**
     * 设备枪号
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subGun(int byteLength, int idx, ByteBuf byteBuf){
        String gun;
        gun = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        gun = FieldAnalysis.analysisBin(gun);
        return gun;
    }

    /**
     * 成功标志
     * 成功标识	BIN码	1Btye	0：成功；1：失败
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subSuccess(int byteLength, int idx, ByteBuf byteBuf){
        String success;
        success = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        success = FieldAnalysis.analysisBin(success);
        return success;
    }

    /**
     * 成功标志
     * 成功标识	BIN码	1Btye	最高位：0：成功；1：失败 低7位：失败原因 1:SM4密钥错误 127:其它原因
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subSuccess2(int byteLength, int idx, ByteBuf byteBuf){
        String success;
        success = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        success = FieldAnalysis.analysisBin(success);
        success = String.valueOf(Integer.toBinaryString(Integer.parseInt(success)).charAt(success.length()-1));

        return success;
    }

    /**
     * 计费模型编码	压缩BCD码	8Byte	全部置0
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subBill(int byteLength, int idx, ByteBuf byteBuf){
        String billId;
        billId = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        billId = FieldAnalysis.analysisBCD(billId);
        return billId;
    }
    /**
     * 交易流水号	压缩BCD 码	16Byte	32位交易代码
     * @param byteLength 字节长度
     * @param idx 下标
     * @param byteBuf 数据
     * @return 返回
     */
    public static String subTranNum(int byteLength, int idx, ByteBuf byteBuf){
        String tranNum;
        tranNum = BinaryTools.subByteBuf(byteLength, idx, byteBuf);
        tranNum = FieldAnalysis.analysisBCD(tranNum);
        return tranNum;
    }


}
